package com.hongyi.modelcontest.modular.wechat.service;

import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import com.alibaba.fastjson.JSONObject;
import com.hongyi.modelcontest.core.util.HttpClientUtil;
import com.hongyi.modelcontest.core.util.SpringbootUtils;
import com.hongyi.modelcontest.modular.wechat.service.impl.WxMsgFactory;
import com.hongyi.modelcontest.modular.wechat.utils.WxUtils;
import com.hongyi.modelcontest.modular.wechat.vo.WxMsg;
import com.hongyi.modelcontest.modular.wechat.vo.WxSengMsg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

@Service
public class WxService {

    private static final Logger logger = LoggerFactory.getLogger(WxService.class);
    @Resource
    private WxTokenService wxTokenService;

    @Value("${WeChat.appID}")
    private String WX_APPID;
    @Value("${WeChat.secret}")
    private String WX_SECRET;
    @Value("${WeChat.token}")
    private String WX_TOKEN;

    /**
     * 获取openId
     *
     * @param code 微信返回的code
     * @return openId
     */
    public String getOpenId(String code) {
        //获取微信用户的openId和accessToken
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=" + WX_APPID +
                "&secret=" + WX_SECRET +
                "&code=" + code +
                "&grant_type=authorization_code";
        String s = HttpClientUtil.httpGetRequest(url);
        JSONObject jsonObject = JSONObject.parseObject(s);
        if (!StringUtils.isEmpty(jsonObject.getString("errcode"))) {
            throw new ServiceException(500, s);
        }
        return jsonObject.getString("openid");
    }

    /**
     * jsdk签名算法
     *
     * @return 签名结果
     */
    public Map<String, String> sign(String urle) {
        String url = "";
        try {
            url = URLDecoder.decode(urle, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String baseAccessToken = wxTokenService.getBaseAccessToken(WX_APPID, WX_SECRET);
        String jsapi_ticket = wxTokenService.getJsApiTicKetAccessToken(baseAccessToken);
        logger.info("wechat jsapi_token:{}", jsapi_ticket);
        String nonce_str = WxUtils.create_nonce_str();
        String timestamp = WxUtils.create_timestamp();
        String signature;
        //注意这里参数名必须全部小写，且必须有序
        String string1 = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + nonce_str +
                "&timestamp=" + timestamp +
                "&url=" + url;
        logger.info("wechat sign str:{}", string1);
        Map<String, String> ret = new HashMap<>();
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes(StandardCharsets.UTF_8));
            signature = WxUtils.byteToHex(crypt.digest());
            ret.put("nonceStr", nonce_str);
            ret.put("appId", WX_APPID);
            ret.put("timestamp", timestamp);
            ret.put("signature", signature);
            return ret;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 校验消息是否来自微信服务器
     *
     * @param timestamp 时间戳
     * @param nonce     随机数
     * @return 加密后字符串
     */
    public String checkWxServer(String timestamp, String nonce) {
        return WxUtils.getSHA1(WX_TOKEN, timestamp, nonce, "");
    }

    /**
     * 发送微信模板消息
     *
     * @param toUser 接收用户openId
     * @param num    模板参数
     */
    public void sendTestMessage(String toUser, Double num) {
        WxMsg testMsg = WxMsgFactory.createTestMsg(toUser, WX_APPID, num);
        String baseToken = wxTokenService.getBaseAccessToken(WX_APPID, WX_SECRET);
        try {
            WxSengMsg.sendMessage(testMsg, baseToken);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String redirectUrl(String state) {
        return "https://open.weixin.qq.com/connect/oauth2/authorize?" +
                "appid=" + WX_APPID +
                "&redirect_uri=" + SpringbootUtils.getRemotUrl() + "/contest/wx/openId" +
                "&response_type=code&scope=snsapi_base" +
                "&state=" + state +
                "#wechat_redirect";
    }

}
